// Ofri Keidar 302933981 group 05

package model.building;

import java.lang.StringBuilder;
import model.apartment.*;

/**
 * The class represents a building. A building holds apartments and allows changing number of rooms of an apartment or its resident name 
 */
public class Building {
	
	private String stName; // name of the street where the building is located	
	private int bldNumber; // building's number in the street	
	private Apartment[] apartments; // holds references to the apartment's in the buildings	
	private int aprtmntNum; // how many apartment there are in the building
	private int id; // building's id

	/**
	 * Constructor- creates a new building with given values
	 * @param stName- street name
	 * @param bldNumber- building number
	 * @param apartments- array of apartments
	 * @param id- building's id
	 */
	public Building(String stName, int bldNumber, Apartment[] apartments, int id) {	

		// initialize attributes according to given values		
		this.stName = stName;		
		this.bldNumber = bldNumber;		
		this.apartments = apartments;		
		aprtmntNum = apartments.length;
		this.id = id;
	}
	
	/**
	 * Returns number of apartments in the building
	 * @return apartments number attribute
	 */
	public int getNumOfAptrmnts() { return aprtmntNum; }
	
	/**
	 * Counts how many penthouses there are in the building and returns calculated value
	 * @return how many penthouses there are in the building
	 */
	public int countPH() {
		
		int phCtr = 0; // penthouse counter
		
		// scan apartment array		
		for (int i = 0; i < aprtmntNum; ++i) {			 
			//check if current element is a penthouse			
			if (apartments[i] instanceof Penthouse) {				
				++phCtr; // increment penthouse counter			
			}		
		}
		
		// return how many penthouses found		
		return phCtr;	
	}

	/**
	 * Calculates total garden area surrounding the building
	 * Sums all building's garden apartments' gardens and returns result.
	 * @return total garden area surrounding the building
	 */
	public double calcGarden() {

		double gardenArea = 0; // total garden area around the building
		
		// scan apartment array		
		for (int i = 0; i < aprtmntNum; ++i) {			
			// check if current element is a garden apartment			
			if (apartments[i] instanceof GardenApartment) {				
				gardenArea += ((GardenApartment)(apartments[i])).getGardenArea();			
			}
		}
				
		// return calculated area		
		return gardenArea;	
	}
	
	/**
	 * Counts how many empty apartments there are in the building and returns calculated value
	 * @return how many empty apartments there are in the building
	 */
	public int countVacant() {
		
		int vacantCtr = 0; // counts vacant apartments		
		
		// scan apartment array		
		for (int i = 0; i < aprtmntNum; ++i) {			
			// check if current element is a vacant apartment			
			if (apartments[i].getName().toString().equals("")) {				
				// current apartment has no resident, increment counter				
				++vacantCtr;			
			}		
		}
		
		// return how many vacant apartments found
		return vacantCtr;
	}
	
	/**
	 * Returns building's printing format. Scans apartment array and uses each apartment's toString() method in order to
	 * create building's string
	 */
	public String toString() {

		// initialize output string
		StringBuilder output = new StringBuilder(String.format("Building address: %d %s", bldNumber, stName));
		
		// scan apartment array and add each apartment's details
		for (int i = 0; i < aprtmntNum; ++i) {			
			output.append(String.format("\nApartment # : %d %s", i+1, apartments[i].toString()));		
		}
		
		// return final string		
		return output.toString();	
	}
	
	/**
	 * Get all apartments in building
	 * @return- apartments in building
	 */
	public Apartment[] getApartments() { return apartments; }

	/**
	 * Returns building's street name
	 * @return street name attribute
	 */
	public String getStreetName() { return stName; }
	
	/**
	 * Returns building's number on street
	 * @return building number attribute
	 */
	public int getBuildingNumber() { return bldNumber; }
	
	/**
	 * Returns building's address
	 * @return building's address
	 */
	public String getBuildingAddress() { return bldNumber + " " + stName; }
	
	/**
	 * If given number is between 1 to number of apartments, reference to the apartment is returned. Otherwise, null is returned
	 * @param aptrmntNum- number of wanted apartment
	 * @return apartment with given number, if exists
	 */
	public Apartment getApartment(int aptrmntNum) {
		
		// boundary check		
		if (aptrmntNum < 1 || aptrmntNum > apartments.length) {			
			return null;		
		}
		
		// apartments' index starts at 1		
		return apartments[aptrmntNum-1];	
	}

	/**
	 * Returns building's id
	 * @return id attribute
	 */
	public int getID() { return id; }
}